#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "cmd.h"

void exec_cmd(struct cmd *cmd)
{
    if(cmd->input != NULL) {
        int fd;
        fd = open(cmd->input, O_RDONLY);
        assert(fd);
        dup2(fd, 0);
        close(fd);
    }
    if(cmd->output != NULL) {
        int fd;
        fd = open(cmd->output, O_CREAT|O_RDWR, 0666);
        assert(fd);
        dup2(fd, 1);
        close(fd);
    }
    int r = execvp(cmd->argv[0], cmd->argv);
    perror("exec");
    exit(0);
}

int builtin_cmd(struct cmd *cmd)
{
    if(cmd->argc==0)
        return 0;
    else
    {
        if(strcmp(cmd->argv[0],"cd") == 0)
        {
            chdir(cmd->argv[1]);
            return 1;
        }
        else if(strcmp(cmd->argv[0],"pwd") == 0)
        {
            char path[1024];
            getcwd(path,sizeof(path));
            printf("%s\n",path);
            return 1;
        }
        else if(strcmp(cmd->argv[0], "exit") == 0)
        {
            exit(0);
        }
    }
    return 0;
}

void exec_pipe_cmd(int cmdc, struct cmd *cmdv)
{
    if (cmdc == 1) 
        exec_cmd(&cmdv[0]);
    else if (cmdc == 2) {
        int fd[2];
        pipe(fd);
        int pid;
        pid = fork();
        if (pid == 0) {
            dup2(fd[1], 1);
            close(fd[0]);
            close(fd[1]);
            exec_cmd(&cmdv[0]);
        }
        dup2(fd[0], 0);
        close(fd[0]);
        close(fd[1]);
        exec_cmd(&cmdv[1]);
    }
    else {
        int fd[2];
        pipe(fd);
        int pid;
        pid = fork();
        if (pid == 0) {
            dup2(fd[1], 1);
            close(fd[0]);
            close(fd[1]);
            exec_pipe_cmd(cmdc-1, cmdv);
        }
        dup2(fd[0], 0);
        close(fd[0]);
        close(fd[1]);
        exec_cmd(&cmdv[cmdc-1]);
    }
}
